/*------------------------------------------------------------------------
 *
 * geqo_misc.c
 *	   杂项打印和调试信息
 *
 * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * src/backend/optimizer/geqo/geqo_misc.c
 *
 *-------------------------------------------------------------------------
 */

/* 贡献者：
   =*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
   *  Martin Utesch				 * 自动控制研究所		   *
   =							 = 矿业与技术大学 =
   *  utesch@aut.tu-freiberg.de  * 德国弗赖贝格				   *
   =*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
 */

#include "postgres.h"

#include "optimizer/geqo_misc.h"


#ifdef GEQO_DEBUG


/*
 * 平均池
 */
static double fc_avg_pool(Pool *fc_pool)
{
	int			fc_i;
	double		fc_cumulative = 0.0;

	if (fc_pool->size <= 0)
		elog(ERROR, "pool_size is zero");

	/*
	 * 由于池中可能包含多个 DBL_MAX 的实例，因此在求和之前除以
	 * pool->size，而不是之后，以避免溢出。这在速度和精度上会损失一些，
	 * 但该例程仅用于调试打印，因此我们不太在乎。
	 */
	for (fc_i = 0; fc_i < fc_pool->size; fc_i++)
		fc_cumulative += fc_pool->data[fc_i].worth / fc_pool->size;

	return fc_cumulative;
}

/* 打印池
 */
void print_pool(FILE *fc_fp, Pool *fc_pool, int fc_start, int fc_stop)
{
	int			fc_i,
				fc_j;

	/* 特别注意 start 和 stop 是有效输入 */

	if (fc_start < 0)
		fc_start = 0;
	if (fc_stop > fc_pool->size)
		fc_stop = fc_pool->size;

	if (fc_start + fc_stop > fc_pool->size)
	{
		fc_start = 0;
		fc_stop = fc_pool->size;
	}

	for (fc_i = fc_start; fc_i < fc_stop; fc_i++)
	{
		fprintf(fc_fp, "%d)\t", fc_i);
		for (fc_j = 0; fc_j < fc_pool->string_length; fc_j++)
			fprintf(fc_fp, "%d ", fc_pool->data[fc_i].string[fc_j]);
		fprintf(fc_fp, "%g\n", fc_pool->data[fc_i].worth);
	}

	fflush(fc_fp);
}

/* 打印世代
 *
 *	 染色体的打印输出：最好，最差，平均值，平均值
 */
void print_gen(FILE *fc_fp, Pool *fc_pool, int fc_generation)
{
	int			fc_lowest;

	/* 获取种群中最低排名基因的索引。 */
	/* 使用倒数第二个，因为最后一个是缓冲区。 */
	fc_lowest = fc_pool->size > 1 ? fc_pool->size - 2 : 0;

	fprintf(fc_fp,
			"%5d | Best: %g  Worst: %g  Mean: %g  Avg: %g\n",
			fc_generation,
			fc_pool->data[0].worth,
			fc_pool->data[fc_lowest].worth,
			fc_pool->data[fc_pool->size / 2].worth,
			fc_avg_pool(fc_pool));

	fflush(fc_fp);
}


void print_edge_table(FILE *fc_fp, Edge *fc_edge_table, int fc_num_gene)
{
	int			fc_i,
				fc_j;

	fprintf(fc_fp, "\nEDGE TABLE\n");

	for (fc_i = 1; fc_i <= fc_num_gene; fc_i++)
	{
		fprintf(fc_fp, "%d :", fc_i);
		for (fc_j = 0; fc_j < fc_edge_table[fc_i].unused_edges; fc_j++)
			fprintf(fc_fp, " %d", fc_edge_table[fc_i].edge_list[fc_j]);
		fprintf(fc_fp, "\n");
	}

	fprintf(fc_fp, "\n");

	fflush(fc_fp);
}

#endif							/* GEQO_DEBUG */
